﻿Imports System.Data.Linq

Public Class OrderDataManager


    ''' <summary>
    ''' Insert/update and delete orders all within the same transaction
    ''' </summary>
    ''' <param name="orders">Updated/Inserted orders and details</param>
    ''' <param name="deletedOrders">Deleted orders</param>
    ''' <param name="deletedDetails">Deleted details</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function SaveAllOrders(ByRef orders As IEnumerable(Of Order), _
                                         ByVal deletedOrders As IEnumerable(Of Order), _
                                         ByVal deletedDetails As IEnumerable(Of OrderPizza)) As Boolean

        Dim hasOrders = (orders IsNot Nothing AndAlso orders.Count > 0)
        Dim hasDeletedOrders = (deletedOrders IsNot Nothing AndAlso deletedOrders.Count > 0)
        Dim hasDeletedDetails = (deletedDetails IsNot Nothing AndAlso deletedDetails.Count > 0)

        If (Not hasOrders) AndAlso (Not hasDeletedOrders) AndAlso (Not hasDeletedDetails) Then
            Return False 'nothing at all to save
        End If

        Dim db As New PizzaManiaDataContext

        For Each o In orders
            'Insert/update orders and details
            If o.Order_ID = 0 Then
                db.Orders.InsertOnSubmit(o)
            Else
                db.Orders.Attach(o, o.IsDirty)
            End If

            For Each d In o.OrderPizzas
                If d.IsDirty Then
                    If d.Order_ID = 0 Then
                        db.OrderPizzas.InsertOnSubmit(d)
                    Else
                        db.OrderPizzas.Attach(d, True)
                    End If
                End If
            Next
        Next

        If hasDeletedOrders Then
            'Delete orders and related details
            db.Orders.AttachAll(deletedOrders, False)
            db.Orders.DeleteAllOnSubmit(deletedOrders)

            For Each o In deletedOrders
                For Each detail In o.OrderPizzas
                    db.OrderPizzas.DeleteOnSubmit(detail)
                Next
            Next
        End If

        If hasDeletedDetails Then
            'Now delete the order details that were passed in
            ' (these order parents were not deleted, just the details)
            db.OrderPizzas.AttachAll(deletedDetails, False)
            db.OrderPizzas.DeleteAllOnSubmit(deletedDetails)
        End If

        Try
            'This will continue to process the 
            ' rest of the orders even if one fails.
            'There's one database transaction for all records that are attached.
            'Since we attached all updates/inserts/deletes 
            ' they will all be processed in one transaction.
            db.SubmitChanges(ConflictMode.ContinueOnConflict)

            'Reset the IsDirty flag
            For Each o In orders
                o.IsDirty = False
                For Each d In o.OrderPizzas
                    d.IsDirty = False
                Next
            Next
        Catch ex As ChangeConflictException
            'TODO: Conflict Handling
            Throw
            Return False
        End Try

        Return True
    End Function

End Class
